Spring Boot
Enterprise Java Development with Spring Framework
Cheat Sheet
Project Setup
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Entry point for any Spring Boot application. Auto-configuration handles most setup.
Common Annotations
@RestController- REST endpoint class@Service- Business logic layer@Repository- Data access layer@Autowired- Dependency injection@Configuration- Configuration class@Bean- Define bean programmatically
application.yml Structure
spring:
datasource:
url: jdbc:mysql://localhost:3306/db
username: root
password: pass
jpa:
hibernate:
ddl-auto: update
Core Concepts
Dependency Injection
Spring's IoC container manages object creation and lifecycle. Use constructor injection for immutability and testability. Avoid field injection in production code.
@Service
public class UserService {
private final UserRepository repo;
public UserService(UserRepository repo) {
this.repo = repo;
}
}
Request-Response Cycle
Request flows through: Dispatcher Servlet → Interceptors → Controller → Service → Repository → Database. Response returns through same stack with formatters applied.
Layered Architecture
- Controller: HTTP request handling
- Service: Business logic & orchestration
- Repository: Data access abstraction
- Entity: Domain model / database mapping
- DTO: Data transfer objects for API
Application Properties
Externalize configuration using application.properties or application.yml.
Access via @Value or @ConfigurationProperties.
Supports profiles: application-dev.yml, application-prod.yml.
Spring Security
Security Configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(
HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
return http.build();
}
}
Key Concepts
- Authentication: Who are you? (verify identity)
- Authorization: What can you do? (check permissions)
- Principal: Currently authenticated user
- GrantedAuthority: Permission/role held by user
- SecurityContext: Holds auth info for current thread
Password Encoding
Always use PasswordEncoder. BCrypt recommended for new projects.
Never store plain passwords.
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Common Patterns
- CSRF protection for form submissions
- CORS configuration for API access
- Role-based access control (RBAC)
- Method-level security with
@PreAuthorize - HTTPS enforcement in production
OAuth2 & JWT
JWT Token Structure
JWT contains three parts separated by dots: header.payload.signature
- Header: Token type and hashing algorithm
- Payload: Claims (user info, permissions, exp time)
- Signature: HMAC or RSA signature for verification
OAuth2 Flow (Authorization Code)
User → App redirects to Auth Server → User grants permission → Auth Server returns code → App exchanges code for token → Token used for API calls
Spring Security OAuth2 Setup
@Bean
public SecurityFilterChain filterChain(
HttpSecurity http) throws Exception {
http.oauth2Login()
.userInfoEndpoint()
.userService(userService);
return http.build();
}
Token Validation
- Verify signature with public key
- Check expiration time (exp claim)
- Validate issuer (iss claim)
- Validate audience (aud claim)
- Store in secure, httpOnly cookies (not localStorage)
JPA / Hibernate
Entity Basics
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
}
Relationships
@OneToMany- One entity to many related@ManyToOne- Many entities to one@ManyToMany- Many to many with join table@OneToOne- One-to-one mapping- Use
mappedByfor bidirectional relations
JPA Repository
public interface UserRepository
extends JpaRepository<User, Long> {
List<User> findByEmail(String email);
@Query("SELECT u FROM User u WHERE " +
"u.status = :status")
List<User> findActive(
@Param("status") String status);
}
JPA Buddy
IntelliJ plugin for JPA/Hibernate productivity. Auto-generates entity classes, visualizes relationships, provides inspections for common issues, and simplifies DDL migrations.
N+1 Query Problem
Occurs when fetching parent entities triggers individual queries for each child.
Solution: Use @Fetch(FetchMode.JOIN), eager loading, or
@Query with JOIN FETCH.
Best Practices
- Use DTOs for API responses, not entities
- Lazy load by default, eager load explicitly
- Index frequently queried columns
- Use transactions for data consistency
- Consider soft deletes with @Where annotation
Swagger / OpenAPI
Springdoc Setup
// pom.xml
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>
springdoc-openapi-starter-
webmvc-ui
</artifactId>
<version>2.0.0</version>
</dependency>
Documenting Endpoints
@GetMapping("/users/{id}")
@Operation(
summary = "Get user by ID",
description = "Retrieve user details")
@ApiResponse(
responseCode = "200",
description = "User found")
public UserDTO getUserById(
@PathVariable Long id) {
// implementation
}
OpenAPI Configuration
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("My API")
.version("1.0.0"));
}
}
Benefits
- Auto-generates interactive API docs
- Live test endpoints from UI
- Generates client SDKs
- Documents request/response schemas
- Standard format for API contracts